package com.danciyixue.boot.dcyx.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.danciyixue.boot.core.security.util.SecurityUtils;
import com.danciyixue.boot.dcyx.converter.UserCurrentProgramConverter;
import com.danciyixue.boot.dcyx.model.entity.Programs;
import com.danciyixue.boot.dcyx.model.entity.Units;
import com.danciyixue.boot.dcyx.model.entity.Series;
import com.danciyixue.boot.dcyx.model.form.UserCurrentProgramForm;
import com.danciyixue.boot.dcyx.service.UnitsService;
import com.danciyixue.boot.dcyx.service.SeriesService;
import com.danciyixue.boot.dcyx.service.UserCurrentProgramService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.danciyixue.boot.dcyx.mapper.UserCurrentUnitsMapper;
import com.danciyixue.boot.dcyx.service.UserCurrentUnitsService;
import com.danciyixue.boot.dcyx.model.entity.UserCurrentUnits;
import com.danciyixue.boot.dcyx.model.form.UserCurrentUnitsForm;
import com.danciyixue.boot.dcyx.model.query.UserCurrentUnitsQuery;
import com.danciyixue.boot.dcyx.model.vo.UserCurrentUnitsVO;
import com.danciyixue.boot.dcyx.converter.UserCurrentUnitsConverter;
import com.danciyixue.boot.common.util.BeanCopyUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

/**
 * 用户当前选择单元信息服务实现类
 *
 * @author youlaitech
 * @since 2025-06-15 16:36
 */
@Slf4j
@Service
@DS("dcyx")
@RequiredArgsConstructor
public class UserCurrentUnitsServiceImpl extends ServiceImpl<UserCurrentUnitsMapper, UserCurrentUnits> implements UserCurrentUnitsService {

    private final UserCurrentUnitsConverter userCurrentUnitsConverter;
    private final UserCurrentProgramService userCurrentProgramService;
    private final UnitsService unitsService;
    private final SeriesService seriesService;

    /**
    * 获取用户当前选择单元信息分页列表
    *
    * @param queryParams 查询参数
    * @return {@link IPage<UserCurrentUnitsVO>} 用户当前选择单元信息分页列表
    */
    @Override
    public IPage<UserCurrentUnitsVO> getUserCurrentUnitsPage(UserCurrentUnitsQuery queryParams) {
        Page<UserCurrentUnitsVO> pageVO = this.baseMapper.getUserCurrentUnitsPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }
    
    /**
     * 获取用户当前选择单元信息表单数据
     *
     * @param id 用户当前选择单元信息ID
     * @return 用户当前选择单元信息表单数据
     */
    @Override
    public UserCurrentUnitsForm getUserCurrentUnitsFormData(Long id) {
        UserCurrentUnits entity = this.getById(id);
        return userCurrentUnitsConverter.toForm(entity);
    }
    
    /**
     * 新增用户当前选择单元信息
     *
     * @param formData 用户当前选择单元信息表单对象
     * @return 是否新增成功
     */
    @Override
    public boolean saveUserCurrentUnits(UserCurrentUnitsForm formData) {
        UserCurrentUnits entity = userCurrentUnitsConverter.toEntity(formData);
        return this.save(entity);
    }
    
    /**
     * 更新用户当前选择单元信息
     *
     * @param id   用户当前选择单元信息ID
     * @param formData 用户当前选择单元信息表单对象
     * @return 是否修改成功
     */
    @Override
    public boolean updateUserCurrentUnits(Long id,UserCurrentUnitsForm formData) {
        UserCurrentUnits entity = userCurrentUnitsConverter.toEntity(formData);
        return this.updateById(entity);
    }
    
    /**
     * 删除用户当前选择单元信息
     *
     * @param ids 用户当前选择单元信息ID，多个以英文逗号(,)分割
     * @return 是否删除成功
     */
    @Override
    public boolean deleteUserCurrentUnitss(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的用户当前选择单元信息数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

    /**
     * 根据用户ID获取当前选中单元
     *
     * @param userId 用户ID
     * @return 用户当前选中单元信息
     */
    @Override
    public UserCurrentUnitsVO getCurrentUnitByUserId(Long userId) {
        // 根据用户ID查询最新的当前单元记录
        LambdaQueryWrapper<UserCurrentUnits> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCurrentUnits::getUserId, userId)
                .orderByDesc(UserCurrentUnits::getUpdateTime)
                .last("LIMIT 1");

        UserCurrentUnits entity = this.getOne(queryWrapper);

        if (entity == null) {
            return null;
        }

        // 将实体转换为VO对象
        UserCurrentUnitsVO vo = userCurrentUnitsConverter.toVO(entity);

        // 补全unitName字段
        if (vo != null && vo.getUnitId() != null) {
            // 通过UnitsService查询单元信息
            Units unit = unitsService.getById(vo.getUnitId());
            if (unit != null) {
                vo.setUnitName(unit.getName());
            }
        }

        // 补全semesterId字段
        if (vo != null && vo.getSeriesId() != null) {
            // 通过SeriesService查询系列信息
            Series series = seriesService.getById(vo.getSeriesId());
            if (series != null) {
                vo.setSemesterId(series.getSemesterId());
            }
        }

        return vo;
    }

    /**
     * 更新用户当前选中单元
     * 兼容：
     * 1. form.unitId 为空的情况；
     *  1. programId 不为空，查询出该 programId 对应的第一个 Unit，取出 unitId 作为选择的 unit；
     * 2. existingEntity 为空，没有记录时，插入新纪录
     * @param form 用户当前单元表单数据
     * @return 是否更新成功
     */
    @Override
    public boolean updateCurrentUnit(UserCurrentUnitsForm form) {
        // 处理 unitId 为空的情况
        if (form.getUnitId() == null && form.getProgramId() != null) {
            // 根据 programId 查询第一个 Unit
            LambdaQueryWrapper<Units> unitQueryWrapper = new LambdaQueryWrapper<>();
            unitQueryWrapper.eq(Units::getProgramId, form.getProgramId())
                    .orderByAsc(Units::getUnitIndex)  // 按单元索引升序排列
                    .last("LIMIT 1");

            Units firstUnit = unitsService.getOne(unitQueryWrapper);
            if (firstUnit != null) {
                form.setUnitId(firstUnit.getId());
            }
        }

        // 检查用户是否已有当前单元记录
        LambdaQueryWrapper<UserCurrentUnits> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCurrentUnits::getUserId, form.getUserId())
                .orderByDesc(UserCurrentUnits::getUpdateTime)
                .last("LIMIT 1");

        UserCurrentUnits existingEntity = this.getOne(queryWrapper);

        // 根据unitId查询单元信息及相关教材信息
        if (form.getUnitId() != null) {
            Units unit = unitsService.getById(form.getUnitId());
            if (unit != null) {
                // 使用 BeanCopyUtils 优化字段设置
                BeanCopyUtils.copyIfNotNull(unit::getProgramId, form::setProgramId);
                BeanCopyUtils.copyIfNotNull(unit::getSeriesId, form::setSeriesId);
                BeanCopyUtils.copyIfNotNull(unit::getName, form::setUnitName);

                // 设置用户信息
                form.setUserId(SecurityUtils.getUserId());
                form.setUsername(SecurityUtils.getUsername());

                // 同步更新用户当前教材信息
                updateUserCurrentProgram(form);
            }
        }

        if (existingEntity != null) {
            // 更新现有记录，entity 内的所有字段都更新
            UserCurrentUnits entity = userCurrentUnitsConverter.toEntity(form);
            entity.setId(existingEntity.getId());
            return this.updateById(entity);
        } else {
            // existingEntity 为空，没有记录时，插入新记录
            // 为新记录设置默认值
            setDefaultValuesForNewRecord(form);
            UserCurrentUnits entity = userCurrentUnitsConverter.toEntity(form);
            return this.save(entity);
        }
    }

    /**
     * 为新记录设置默认值
     *
     * @param form 用户当前单元表单数据
     */
    private void setDefaultValuesForNewRecord(UserCurrentUnitsForm form) {
        // 为必填字段设置默认值（如果为空）
        if (form.getErrors() == null) {
            form.setErrors(0);
        }
        if (form.getRights() == null) {
            form.setRights(0);
        }
        if (form.getIsEnd() == null) {
            form.setIsEnd(0);
        }
        if (form.getErrorWordInfo() == null) {
            form.setErrorWordInfo("");
        }
        if (form.getWordIdx() == null) {
            form.setWordIdx(0);
        }
    }

    /**
     * 同步更新用户当前教材信息
     *
     * @param form 用户当前单元表单数据
     * @return 是否更新成功
     */
    private boolean updateUserCurrentProgram(UserCurrentUnitsForm form) {
        // 只有在programId有效时才更新教材信息
        if (form.getProgramId() == null) {
            return false;
        }
        // 创建教材表单对象
        UserCurrentProgramForm programForm = new UserCurrentProgramForm();
        programForm.setUserId(form.getUserId());
        programForm.setUsername(form.getUsername());
        programForm.setProgramId(form.getProgramId());
        programForm.setSeriesId(form.getSeriesId());
        // 注入UserCurrentProgramService
//        UserCurrentProgramService userCurrentProgramService = SpringUtils.getBean(UserCurrentProgramService.class);
        // 调用教材服务更新方法
        return userCurrentProgramService.updateCurrentProgram(programForm);
    }

    /**
     * 标记单元学习完成
     *
     * @param unitId 单元ID
     * @return 操作结果
     */
    @Override
    public boolean completeUnit(Long unitId) {
        // 获取当前用户ID
        Long userId = SecurityUtils.getUserId();

        // 查询用户当前学习的单元记录
        LambdaQueryWrapper<UserCurrentUnits> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCurrentUnits::getUserId, userId)
                    .eq(UserCurrentUnits::getUnitId, unitId);

        UserCurrentUnits userCurrentUnit = this.getOne(queryWrapper);

        // 如果记录不存在，返回失败
        if (userCurrentUnit == null) {
            return false;
        }

        // 标记单元为已完成
        userCurrentUnit.setIsEnd(1);

        // 更新记录
        return this.updateById(userCurrentUnit);
    }

    /**
     * 根据单元学习统计信息更新用户当前单元
     * 当单元学习统计信息发生变化时，同步更新用户当前单元表
     *
     * @param userId 用户ID
     * @param unitId 单元ID
     * @return 是否更新成功
     */
    @Override
    public boolean updateCurrentUnitFromStats(Long userId, Long unitId) {
        // 参数校验
        if (userId == null || unitId == null) {
            return false;
        }

        try {
            // 查询单元信息
            Units unit = unitsService.getById(unitId);
            if (unit == null) {
                return false;
            }

            // 查询用户当前单元记录
            LambdaQueryWrapper<UserCurrentUnits> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserCurrentUnits::getUserId, userId)
                    .orderByDesc(UserCurrentUnits::getUpdateTime)
                    .last("LIMIT 1");

            UserCurrentUnits existingEntity = this.getOne(queryWrapper);

            if (existingEntity == null) {
                // 不存在记录，创建新记录
                UserCurrentUnits newEntity = new UserCurrentUnits();
                newEntity.setUserId(userId);
                newEntity.setUnitId(unitId);

                // 使用 BeanCopyUtils 设置单元相关信息
                BeanCopyUtils.copyIfNotNull(unit::getProgramId, newEntity::setProgramId);
                BeanCopyUtils.copyIfNotNull(unit::getSeriesId, newEntity::setSeriesId);
                BeanCopyUtils.copyIfNotNull(unit::getName, newEntity::setUnitName);

                // 设置默认值
                newEntity.setErrors(0);
                newEntity.setRights(0);
                newEntity.setIsEnd(0);
                newEntity.setErrorWordInfo("");

                return this.save(newEntity);
            } else {
                // 存在记录，更新单元信息
                UserCurrentUnits updateEntity = new UserCurrentUnits();
                updateEntity.setId(existingEntity.getId());
                updateEntity.setUnitId(unitId);

                // 使用 BeanCopyUtils 更新单元相关信息
                BeanCopyUtils.copyIfNotNull(unit::getProgramId, updateEntity::setProgramId);
                BeanCopyUtils.copyIfNotNull(unit::getSeriesId, updateEntity::setSeriesId);
                BeanCopyUtils.copyIfNotNull(unit::getName, updateEntity::setUnitName);

                return this.updateById(updateEntity);
            }
        } catch (Exception e) {
            // 记录日志但不抛出异常，避免影响主业务流程
            log.error("更新用户当前单元失败，userId: {}, unitId: {}", userId, unitId, e);
            return false;
        }
    }
}
